#include "ExportGui.h"
#include "Util.h"
#include "Performance.h"
#include <iostream>

using namespace std;

ExportGui* ExportGui::instant;

int s_gui_max_element;

ExportGui* ExportGui::getInstant()
{
	if ( instant == NULL )
		instant = new ExportGui();
	return instant;
}

int ExportGui::isGuiSuccess ( char* guiName )
{
	int success = 1;

	//check gtsFile
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );
	if ( !Util::getInstant()->isExist( gtsFile ) )
	{
		success = 0;
		cout << "---------------------" << gtsFile << " not exist " <<endl;
	}
	//check level path
	vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
	for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
	{
		if ( !Util::getInstant()->isExist( *levelName ) )
		{
			success = 0;
			cout << "---------------------" << *levelName << " not exist " <<endl;
		}
	}

	return success;
}

void ExportGui::buildBegin( char* guiName )
{
	char* gtsName  = Util::getInstant()->getGtsFile( guiName );
	int maxTemp = Util::getInstant()->getTemplateMax( gtsName );
	int maxLevel = Util::getInstant()->getGuiLevelMax( guiName );
	int maxElement = getElementMax( guiName );

	s_gui_max_element = maxElement;
		 
	FILE* outF = fopen ( "GuiDefine.h", "w" );
	fprintf ( outF, "#ifndef _GUI_DEFINE_H_" );
	fprintf ( outF, "\n#define _GUI_DEFINE_H_" );
	fprintf ( outF, "\n\n#define GUI_MAX_TEMPLATE %d", maxTemp );
	fprintf ( outF, "\n#define GUI_MAX_LEVEL %d", maxLevel );
	fprintf ( outF, "\n#define GUI_MAX_ELEMENT %d", maxElement );
	fprintf ( outF, "\n#define GUI_MAX_VALUE_PARAM %d", VALUE_PARAM_MAX );
	fclose ( outF );
}

void ExportGui::buildEnd()
{
	FILE* outF = fopen ( "GuiDefine.h", "a" );	
	fprintf ( outF, "\n#endif" );
	fclose ( outF );
}

void ExportGui::buildTemplateID ( char* gtsFile )
{
	int countID = 0;
	char line[200], temp[100], tempString[100];
	FILE* f = fopen ( gtsFile, "r" );
	FILE* outF = fopen ( "GuiDefine.h", "a" );	
		
	fprintf ( outF, "\n\nclass GUI_TEMPLATE\n{\npublic:" );
	

	while ( !feof ( f ) )
	{
		fgets( line, sizeof ( line ), f );
		if ( line[0] == 'T' && line[1] == 'E' && line[2] == 'M' && line[3] == 'P' && line[4] == 'L' && line[5] == 'A' && line[6] == 'T' && line[7] == 'E')
		{			
			sscanf ( &line[1], "%s" "%s" "%s", &temp, &temp, &tempString );
			//cut ""
			for (int i = 0; i < strlen ( tempString ) - 2; i++ )
				tempString[i] = tempString[i + 1];
			tempString[strlen ( tempString ) - 2] = '\0';
			
			fprintf ( outF, "\n\tstatic const int %s = %d;", strupr(tempString), countID++ );
		}

		memset ( line, 0, sizeof ( line ) );
		memset ( line, 0, sizeof ( tempString ) );
	}
	fprintf ( outF, "\n};" ); 
	fclose ( f );
	fclose ( outF );
}
void ExportGui::buildGuiLevelID ( char* guiName )
{
	FILE* f = fopen ( guiName, "r" );
	FILE* outF = fopen ( "GuiDefine.h", "a" );	
	int levelCount = 0;

	fprintf ( outF, "\n\nclass GUI_LEVEL\n{\npublic:" );
	vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
	for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
	{
		char temp[100], levelID[50];
		char * levelPath = *levelName;
		for ( int i = strlen ( levelPath ) - 1; i >= 0; i-- )
		{
			if ( levelPath[i] == '\\' )
			{
				temp[strlen ( ( *levelName ) ) - 1 - i] = '\0';
				break;
			}
			temp[strlen ( ( *levelName ) ) - 1 - i] = levelPath[i];
		}
		for ( int i = strlen( temp ) -1; i >=0; i-- )
			levelID[strlen( temp ) -1 - i] = temp[i];

		levelID[strlen( temp ) - strlen( ".level" )] = '\0';

		fprintf ( outF, "\n\tstatic const int %s = %d;", strupr ( levelID), levelCount++ );
	}

	fprintf ( outF, "\n};" ); 
	fclose ( outF );
}

void ExportGui::buildLevelClass ( char* gtsFile, char* levelName )
{	
	char line[200], elementID[100], temp[20];	
//	char* line;		
	int countElememt = 0;

	FILE* fIn = fopen ( levelName, "r" );
	FILE* outF = fopen ( "GuiDefine.h", "a" );	

	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << levelName;		
		return  ;
	}

	while ( !feof ( fIn ) )
	{				
		fgets( line, sizeof( line ),fIn );
		//line = Util::getInstant()->cutSpaceBefore ( lineOrigin );

		if ( line[0] == '\"' ) ////get class name
		{
			char layerIDName[100];
			sscanf ( &line[0], "%s", &layerIDName );
			for ( int i = 0; i < strlen ( layerIDName ) - 2; i++ )
				layerIDName[i] = layerIDName[i + 1];
			layerIDName[strlen ( layerIDName ) - 2] = '\0';

			fprintf ( outF, "\n\nclass LEVEL_%s\n{\npublic:", layerIDName);
			memset ( line, 0, sizeof ( line ) );
			memset ( line, 0, sizeof ( layerIDName ) );				
		}
		else if ( Util::getInstant()->stringContainString( line, "LAYER" ) )
		{
			sscanf ( &line[0], "%s" "%s" "%s", &temp, &temp, &elementID );
			for ( int i = 1; i < strlen( elementID ); i++ )
			{
				if ( elementID[i] != '-' )
				{
					elementID[i - 1] = elementID[i];
				}
				else
				{
					elementID[i - 1] = '\0';
				}
			}

			if ( Util::getInstant()->getTemplateID ( gtsFile, elementID ) == -1 ) //not have to template 
				fprintf ( outF, "\n\tstatic const int %s = %d;", elementID, countElememt );
			else
				fprintf ( outF, "\n\tstatic const int %s_%d = %d;", elementID, countElememt, countElememt );
			countElememt++;
		}
			
		memset ( line, 0, sizeof ( line ) );		
	}
	fprintf ( outF, "\n};" );
	fclose (fIn);	
	fclose (outF);		
}

int ExportGui::getElementLevel ( char* gtsFile, char* levelName )
{	
	char line[200], elementID[100], temp[20];	
//	char* line;		
	int countElememt = 0;

	FILE* fIn = fopen ( levelName, "r" );	

	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << levelName;		
		return 0 ;
	}

	while ( !feof ( fIn ) )
	{				
		fgets( line, sizeof( line ),fIn );
		//line = Util::getInstant()->cutSpaceBefore ( lineOrigin );

		if ( line[0] == '\"' ) ////get class name
		{
			char layerIDName[100];
			sscanf ( &line[0], "%s", &layerIDName );
			for ( int i = 0; i < strlen ( layerIDName ) - 2; i++ )
				layerIDName[i] = layerIDName[i + 1];
			layerIDName[strlen ( layerIDName ) - 2] = '\0';
			
			memset ( line, 0, sizeof ( line ) );
			memset ( line, 0, sizeof ( layerIDName ) );				
		}
		else if ( Util::getInstant()->stringContainString( line, "LAYER" ) )
		{
			sscanf ( &line[0], "%s" "%s" "%s", &temp, &temp, &elementID );
			for ( int i = 1; i < strlen( elementID ); i++ )
			{
				if ( elementID[i] != '-' )
				{
					elementID[i - 1] = elementID[i];
				}
				else
				{
					elementID[i - 1] = '\0';
				}
			}
						
			countElememt++;
		}
			
		memset ( line, 0, sizeof ( line ) );		
	}
	
	fclose (fIn);		
	return countElememt;
}
void ExportGui::buildAllLevelClass ( char* guiName )
{
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );	
	vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
	for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
	{
		buildLevelClass ( gtsFile, (*levelName) );
	}	
}

int ExportGui::getElementMax ( char* guiName )
{
	int elementMax = 0;
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );	
	vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
	for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
	{
		if ( elementMax < getElementLevel ( gtsFile, (*levelName) ) )
			elementMax = getElementLevel ( gtsFile, (*levelName) ) ;
	}
	return elementMax;
}

std::vector< Value_Param > ExportGui::getValueLevel  ( char* gtsFile, char* levelName )
{
	char line[200], temp[50];	
	char* lineTemp;
	vector< Value_Param > elementArray;
	SpriteAurora* spriteArray = Performance::getInstant()->LoadAllSprite( Util::getInstant()->getSpriteListFile ( gtsFile ) );

	FILE* fIn = fopen ( levelName, "r" );	

	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << levelName;		
		return elementArray ;
	}

	while ( !feof ( fIn ) )
	{				
		fgets( line, sizeof( line ),fIn );		

		if ( Util::getInstant()->stringContainString( line, "LAYER OBJECT_LAYER" ) )
		{
			/*
			{
				FLAGS 0x00000000
				ID 51
				POS 328 203
				ANCHOR 0 0
				ANCHOR_2 0 0
				DISABLE_OBJECT 0
				TEMPLATE "StringBased"
				PARAMS 0="MEDIUM" 0="MENU_TOUCH_TO_CONTINUE" 1="true" 2="RIGHT" 1="CENTER"
			}
			*/
			// get POS 328 203
			int value[VALUE_PARAM_MAX]; //0: template, 1: x, 2: y
			for ( int i = 0; i < VALUE_PARAM_MAX; i++ )
				value[i] = -1;
			fgets( line, sizeof( line ),fIn );	
			fgets( line, sizeof( line ),fIn );	
			fgets( line, sizeof( line ),fIn );	
			memset ( line , 0, sizeof ( line ) );	
			fgets( line, sizeof( line ),fIn );	
			lineTemp = Util::getInstant()->keepNumberInString( line );
			sscanf( &lineTemp[0], "%d" "%d", &value[1], &value[2] );
			
			//get TEMPLATE "StringBased"
			fgets( line, sizeof( line ),fIn );	
			fgets( line, sizeof( line ),fIn );	
			fgets( line, sizeof( line ),fIn );	
			memset ( line , 0, sizeof ( line ) );	
			fgets( line, sizeof( line ),fIn );	
			char _template[50];
			sscanf( &line[0], "%s" "%s", &temp, &_template );
			//"SelectPoint"
			// cut ""
			for ( int i = 0 ; i < strlen ( _template ) - 2; i++ )
				_template[i] = _template[i + 1];
			_template[strlen ( _template ) - 2] = '\0';
			value[0] = Util::getInstant()->getTemplateID ( gtsFile, _template );

			//get PARAMS 0="MEDIUM" 0="MENU_TOUCH_TO_CONTINUE" 1="true" 2="RIGHT" 1="CENTER"
			memset ( line , 0, sizeof ( line ) );	
			fgets( line, sizeof( line ),fIn );	
			lineTemp = Util::getInstant()->keepNumberInString( line );
			sscanf( &lineTemp[0], "%d" "%d" "%d" "%d" "%d" "%d" "%d", &value[3], &value[4], &value[5], &value[6], &value[7], &value[8], &value[9] );

			//convert frameID -> moduleID of sprite
			if ( Util::getInstant()->getTemplateID ( gtsFile, "SpriteBased") == value[0] && value[4] != -1 )
			{
				value[4] = Performance::getInstant()->getModuleID ( value[3], value[4], spriteArray );
			}

			Value_Param _value;
			for ( int i = 0 ; i < VALUE_PARAM_MAX; i ++ )
				_value.value[i] = value[i];
			elementArray.push_back( _value );
		}
		
		memset ( line , 0, sizeof ( line ) );			
		
	}
	fclose (fIn);
	return elementArray;
}

void ExportGui::buildAllLevel( char* guiName )
{
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );		
	FILE* outF = fopen ( "GuiDefine.h", "a" );	

	if ( s_gui_max_element != 0 )
	{
		fprintf( outF, "\n\nstatic int s_guiLevel[GUI_MAX_LEVEL][GUI_MAX_ELEMENT][GUI_MAX_VALUE_PARAM] = \n{" );

		vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
		for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
		{
			fprintf( outF, "\n\t{");
			vector < Value_Param > valueArray = getValueLevel ( gtsFile, (*levelName) );
			for ( vector < Value_Param >::iterator value = valueArray.begin(); value != valueArray.end(); value++ )
			{			
				for ( int i = 0; i < VALUE_PARAM_MAX; i++ )
				{
					if ( i == 0 )
						fprintf( outF, "\n\t\t{ %d,", (*value).value[i]);
					else if ( i == VALUE_PARAM_MAX - 1 )
						fprintf( outF, " %d },", (*value).value[i]);
					else
						fprintf( outF, " %d,", (*value).value[i] );
				}
			}
			fprintf( outF, "\n\t},");
		}
		fprintf( outF, "\n};");
	}
	else
		fprintf( outF, "\n\nstatic int s_guiLevel[1][1][1];" );
	fclose( outF );
}

void ExportGui::buildArrayElementMax ( char* guiName )
{
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );		
	FILE* outF = fopen ( "GuiDefine.h", "a" );	
	fprintf( outF, "\n\nstatic int s_guiElementMax[GUI_MAX_LEVEL]= {" );

	vector< char* > levelArray = Util::getInstant()->getLevelFileName ( guiName );
	for ( vector< char* >::iterator levelName = levelArray.begin(); levelName != levelArray.end(); levelName++ )
	{
		fprintf( outF, " %d,", getElementLevel ( gtsFile, (*levelName) ) );
	}
	fprintf( outF, " };");
	fclose( outF );
}


void ExportGui::exportGuiDefine ( char* guiName )
{
	char* gtsFile = Util::getInstant()->getGtsFile ( guiName );
	buildBegin( guiName );	
	buildTemplateID ( gtsFile );
	buildGuiLevelID ( guiName );	
	buildAllLevelClass ( guiName );	
	buildAllLevel ( guiName );
	buildArrayElementMax ( guiName );
	buildEnd();
}